package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"strconv"
	"strings"
	"syscall"
	"time"
)

type MetricValue struct {
	Metric    string  `json:"metric"`
	Endpoint  string  `json:"endpoint"`
	Timestamp int64   `json:"timestamp"`
	Value     float64 `json:"value"`
	Tags      string  `json:"tags"`
}

func main() {
	if len(os.Args) < 2 {
		panic("exec <metric>")
	}
	metric := os.Args[1]

	stdin, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}
	script := string(stdin)

	monitortag := os.Getenv("monitortag")

	username := os.Getenv("user")
	if username == "" {
		username = "nobody"
	}

	endpoint, err := os.Hostname()
	if err != nil {
		panic(err)
	}
	endpoint = strings.Replace(endpoint, "w-", "", 1)

	timestamp := time.Now().Unix()

	cmd := exec.Command("/bin/bash", "-c", script)

	if username != "root" {
		user, err := user.Lookup(username)
		if err != nil {
			panic(err)
		}
		uid, _ := strconv.Atoi(user.Uid)
		gid, _ := strconv.Atoi(user.Gid)
		cmd.SysProcAttr = &syscall.SysProcAttr{}
		cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
	}

	output, err := cmd.CombinedOutput()
	if err != nil {
		panic(err)
	}

	data := strings.TrimSpace(string(output))
	value, err := strconv.ParseFloat(data, 64)
	if err != nil {
		panic(err)
	}
	metricValue := MetricValue{
		Metric:    metric,
		Endpoint:  endpoint,
		Timestamp: timestamp,
		Value:     value,
		Tags:      monitortag,
	}

	metricValues := []MetricValue{metricValue}
	result, err := json.Marshal(metricValues)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(result))
}
